package cn.wolfcode.wolf2w.controller;

import cn.wolfcode.wolf2w.domain.*;
import cn.wolfcode.wolf2w.elasticseach.domain.DestinationEs;
import cn.wolfcode.wolf2w.elasticseach.domain.StrategyEs;
import cn.wolfcode.wolf2w.elasticseach.domain.TravelEs;
import cn.wolfcode.wolf2w.elasticseach.domain.UserInfoEs;
import cn.wolfcode.wolf2w.elasticseach.query.SearchQueryObject;
import cn.wolfcode.wolf2w.elasticseach.service.ISearchService;
import cn.wolfcode.wolf2w.elasticseach.vo.SearchResultVO;
import cn.wolfcode.wolf2w.query.BannerQueryObject;
import cn.wolfcode.wolf2w.service.*;
import cn.wolfcode.wolf2w.util.JsonResult;
import cn.wolfcode.wolf2w.util.ParamMap;
import org.apache.commons.collections.list.PredicatedList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class SearchController {

    @Autowired
    private ITravelService travelService;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private IBannerService bannerService;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private ISearchService searchService;

    @GetMapping("/q")
    public Object Search(SearchQueryObject qo) throws UnsupportedEncodingException {
        //编码: %E5%B9%BF%E5%B7%9E --> 解码: 广州
        //url 传入中文时, 会自动将中文进行编码, 此时需要解码
        String kw = URLDecoder.decode(qo.getKeyword(), "UTF-8");
        qo.setKeyword(kw);
        switch (qo.getType()) {
            case SearchQueryObject.TYPE_DEST:
                return searchDest(qo);
            case SearchQueryObject.TYPE_STRATEGY:
                return searchStrategy(qo);
            case SearchQueryObject.TYPE_TRAVEL:
                return searchTravel(qo);
            case SearchQueryObject.TYPE_USER:
                return searchUser(qo);
            default:
                return searchAll(qo);
        }
    }


    //查所有
    private Object searchAll(SearchQueryObject qo) {
        SearchResultVO vo = new SearchResultVO();
        long total = 0L; //搜索结果总条数
        Page<Strategy> sts = this.createStrategyPage(qo);
        vo.setStrategys(sts.getContent());

        total += sts.getTotalElements();  //攻略分页总记录数

        Page<Travel> ts = this.createTravelPage(qo);
        vo.setTravels(ts.getContent());
        total += ts.getTotalElements();

        Page<UserInfo> us = this.createUserInfoPage(qo);
        vo.setUsers(us.getContent());
        total += us.getTotalElements();

        Page<Destination> ds = this.createDestPage(qo);
        vo.setDests(ds.getContent());
        total += ds.getTotalElements();
        vo.setTotal(total);

        return JsonResult.success(new ParamMap().put("qo", qo).put("result", vo));
    }


    //查攻略
    private Object searchStrategy(SearchQueryObject qo) {
        //通过页面输入关键词进行全文搜索(结果需要高亮显示)
        return JsonResult.success(new ParamMap().put("qo", qo).put("page", this.createStrategyPage(qo)));
    }

    //查用户
    private Object searchUser(SearchQueryObject qo) {
        //通过页面输入关键词进行全文搜索(结果需要高亮显示)
        return JsonResult.success(new ParamMap().put("qo", qo).put("page", this.createUserInfoPage(qo)));
    }

    //查游记
    private Object searchTravel(SearchQueryObject qo) {
        //通过页面输入关键词进行全文搜索(结果需要高亮显示)
        return JsonResult.success(new ParamMap().put("qo", qo).put("page", this.createTravelPage(qo)));
    }


    private Page<Strategy> createStrategyPage(SearchQueryObject qo) {
        Page<Strategy> sts = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME, Strategy.class, qo, "title", "subTitle", "summary");
        return sts;
    }

    private Page<Travel> createTravelPage(SearchQueryObject qo) {
        return searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME, Travel.class, qo, "title", "summary");
    }

    private Page<UserInfo> createUserInfoPage(SearchQueryObject qo) {
        return searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME, UserInfo.class, qo, "nickname", "city");
    }

    private Page<Destination> createDestPage(SearchQueryObject qo) {
        Class<Destination> clz = Destination.class;
        return searchService.searchWithHighlight(DestinationEs.INDEX_NAME, DestinationEs.TYPE_NAME, Destination.class, qo, "name", "info");
    }

    private Object searchDest(SearchQueryObject qo) {
        ParamMap paramMap = new ParamMap();

        Destination dest = destinationService.queryName(qo.getKeyword());
        String id = destinationService.getByName(qo.getKeyword());
        List<Travel> travels = travelService.findByDestId(id);
        List<Strategy> strategys = strategyService.getByDestId(id);
        List<UserInfo> userInfos = userInfoService.getByCity(qo.getKeyword());

        SearchResultVO vo = new SearchResultVO();
        vo.setTravels(travels);
        vo.setStrategys(strategys);
        vo.setUsers(userInfos);
        vo.setTotal(strategys.size() + travels.size() + userInfos.size() + 0L);
        paramMap.put("qo", qo).put("result", vo);

        return JsonResult.success(new ParamMap().put("result", vo).put("qo", qo).put("dest", dest));
    }
}
